#include<iostream>
#include<unistd.h>
#include<pthread.h>
#include<vector>
#include<string>

void* thread_routine(void* args)
{
    std::string name = static_cast<const char*>(args);
    int cnt = 5;
    while(cnt--)
    {
        printf("我是新线程, name: %s , id:0x%lx\n", name.c_str() , pthread_self());
        sleep(1);
    }

    //线程退出方式，调用pthread_exit(nullptr);
    //exit(1);会使得当前进程退出，即使得当前进程的所有线程退出
    pthread_exit((void*)10); 
}

int main()
{
    pthread_t tid;
    //创建新线程
    int n = pthread_create(&tid ,nullptr , thread_routine,(void*)"thread-1");
    //pthread_create 中的tid 其实本质上是库当中描述线程这个结构体变量的地址，结构struct tcb 当中
    //可以存放 lwp , 以及返回值 void* ret; 返回的本质也是写入
    if(!n){}
    printf("主线程id: 0x%lx , 新线程id: 0x%lx\n", pthread_self() , tid);
    //等待
    void* ret;
    int m = pthread_join(tid,&ret);//第二个参数为所等待线程的退出信息的指针
    if(m==0)
    {
        //获取新线程的返回值
        //在服务器上机子为64位，地址为8byte ,所以此处使用long long 来强转较为合适
        printf("新线程的返回值：%lld\n" , (long long)ret);
    }

    sleep(3);
    printf("主进程退出\n");
    return 0;
}

// volatile int gval = 100;//同一地址空间的多线程，共享资源
// //资源都是共享的，只要知道有就有权限可以访问；但是介于每个线程都有自己的函数作用域，有自己的栈帧
// //所有线程呈现出来各自有各自的数据

// void* thread_routine(void* args)
// {
//     // std::string name = (const char*)args;
//     std::string name = static_cast<const char*>(args);
//     int cnt = 5;
//     printf("我是新线程 , name:%s\n" , name.c_str());

//     while(cnt--)
//     {
//         // printf("我是新线程 , name:%s, gval: %d , &gavl: %p\n" , name.c_str() , gval ,&gval);
//         // gval++;
//         sleep(1);   
//     }
//     return nullptr;
// }

// //现象：一个进程两个执行流 
// int gnum = 10;

// int main()
// {
//     std::vector<pthread_t> tids;//将所创建线程的id 放入数组中以便等待回收
//     //创建线程
//     for(int i = 0;i<gnum;i++)
//     {
//         pthread_t tid;
//         //输出型参数，线程id  设置线程熟悉，NULL为默认 新线程所要执行的函数方法，参数为void*，返回值也为void* 传给函数的参数
//         // char idbuffer[64];
//         char* name = new char[64];
//         snprintf(name , 64 , "thread-%d" , i+1);
//         int n = pthread_create(&tid , NULL , thread_routine , (void*)name);
//         if(n!=0)
//         {
//             exit(1);
//         }
//         //将线程id 放入数组中
//         tids.push_back(tid);
//         // sleep(1);
//     }

//     //打印一下tids 中的数据信息
//     for(auto& e : tids)
//         printf("新线程id:0x%lx\n" ,e);

//     //等待所有的子进程
//     for(auto& e: tids)
//     {
//         pthread_join(e , nullptr);
//         printf("新线程结束，退出的新线程是：0x%lx\n",e);
//     }
//     // sleep(4);
//     printf("主进程退出\n");
//     //主线程
//     // while(true)
//     // {
//     //     printf("我是主线程……, tid: 0x%lx , gval: %d , &gavl: %p\n",tid, gval ,&gval);//tid 不是lwp 
//     //     sleep(1);
//     // }
//     return 0;//主线程退出意味着当前进程退出，进程退出会释放数据意味着所有的线程也会退出
// }

// int main()
// {
//     pid_t pid = getpid();
//     pid_t ppid = getppid();
//     while(true)
//     {
//         printf("当前进程pid:%d , 其父进程pid:%d\n" , pid , ppid);
//         sleep(1);
//     }
//     //父进程
//     return 0;
// }

    // pid_t id = fork();
    // if(id==0)
    // {
    //     std::cout << "我是子进程: " <<  getpid()  << " , 父进程为：%d" << getppid() << std::endl;
    //     exit(0);
    // }